﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevelopAssistant.Service;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using NORM.Common;

namespace DevelopAssistant.AddIn.DataPie
{
    [ToolboxItem(false)]
    public partial class Summary : UserControl
    {
        int table_count = 0;
        int view_count = 0;
        int procedure_count = 0;
        int function_count = 0;
        int total_count = 0;        

        Pen pen = null;

        string versionInfo = "";

        Dictionary<string, double> data = new Dictionary<string, double>();

        Dictionary<string, DataBaseFileInfo> file = new Dictionary<string, DataBaseFileInfo>();

        public Summary()
        {
            InitializeComponent();

            this.SetStyle(ControlStyles.ResizeRedraw |
              ControlStyles.OptimizedDoubleBuffer |
              ControlStyles.AllPaintingInWmPaint, true);
            this.UpdateStyles();

            pen = new Pen(new SolidBrush(SystemColors.ControlDark), 1.0f);
        }

        public void BindInfo(DataBaseServer dataBaseServer)
        {
            using (DataBaseHelper db = new DataBaseHelper(dataBaseServer.ConnectionString, dataBaseServer.ProviderName))
            {
                try
                {
                    var objects = db.GetDataBaseObjects();

                    foreach (DataRow dr in objects.Rows)
                    {
                        string objectType = dr["table_type"] + "";
                        switch (objectType)
                        {
                            case "table": table_count = table_count + 1; break;
                            case "view": view_count = view_count + 1; break;
                            case "procedure": procedure_count = procedure_count + 1; break;
                            case "function": function_count = function_count + 1; break;
                        }
                        total_count = total_count + 1;
                    }

                    if (table_count > 0)
                        data.Add("表", (double)table_count);
                    if (view_count > 0)
                        data.Add("视图", (double)view_count);
                    if (procedure_count > 0)
                        data.Add("存储过程", (double)procedure_count);
                    if (function_count > 0)
                        data.Add("函数", (double)function_count);

                    var files = db.GetDataBaseFiles();

                    foreach (DataRow dr in files.Rows)
                    {
                        DataBaseFileInfo dbfinf = new DataBaseFileInfo();
                        dbfinf.Logical_Name = dr["逻辑名称"] + "";
                        dbfinf.Physical_Name = dr["路径"] + "";

                        double maxsize = -1;
                        double.TryParse(dr["最大限制"] + "", out maxsize);
                        dbfinf.Maxsize = maxsize;

                        double size = -1;
                        double.TryParse(dr["初始大小"] + "", out size);
                        dbfinf.Size = size;

                        file.Add(dbfinf.Logical_Name, dbfinf);
                    }

                    versionInfo = db.GetVesion();

                    this.Invalidate();

                }
                catch (Exception ex)
                {
                    DevelopAssistant.Common.NLogger.LogError(ex);
                }
            }

        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics graphic = e.Graphics;

            Rectangle objectes_rect = new Rectangle(0, 2, this.Width - 2, this.Height * 64 / 100);

            Rectangle files_rect = new Rectangle(0, 2 + objectes_rect.Height + 6, this.Width - 2, this.Height * 36 / 100 - 10);

            DrawPie(graphic, objectes_rect.Width - 20, objectes_rect.Height - 20, objectes_rect.Height / 2 - 60, "微软雅黑", data);

            DrawFile(graphic, files_rect.Width, files_rect.Height, files_rect.Left, files_rect.Top, "微软雅黑");

            graphic.SmoothingMode = SmoothingMode.None;
            graphic.PixelOffsetMode = PixelOffsetMode.Default;

            graphic.DrawRectangle(pen, objectes_rect);
            graphic.DrawRectangle(pen, files_rect);

        }

        /// <summary>       
        /// 根据四率 得到扇形图       
        /// </summary>       
        /// <param name="width"></param>       
        /// <param name="heigh"></param>       
        /// <param name="r">饼图半径</param>       
        /// <param name="familyName"></param>       
        /// <param name="data"></param>   
        /// <returns></returns>      
        public Bitmap GetBitmap(int width, int heigh, int r, string familyName, Dictionary<string, double> data)
        {

            Bitmap bitmap = new Bitmap(width, heigh);
            Graphics graphics = Graphics.FromImage(bitmap);
            //用白色填充整个图片，因为默认是黑色          

            graphics.Clear(Color.White);
            //抗锯齿          
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            //高质量的文字          
            graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
            //像素均偏移0.5个单位，以消除锯齿          
            graphics.PixelOffsetMode = PixelOffsetMode.Half;
            //第一个色块的原点位置           
            PointF basePoint = new PointF(10, 20);

            //色块的大小          
            SizeF theSize = new SizeF(45, 16);
            //第一个色块的说明文字的位置           
            PointF textPoint = new PointF(basePoint.X + 50, basePoint.Y);
            foreach (var item in data)
            {
                RectangleF baseRectangle = new RectangleF(basePoint, theSize);
                //画代表色块              
                graphics.FillRectangle(new SolidBrush(getColor(item.Key.ToString())), baseRectangle);
                graphics.DrawString(item.Key.ToString() + " :" + item.Value, new Font(familyName, 11), Brushes.Black, textPoint);
                basePoint.Y += 30;
                textPoint.Y += 30;
            }

            //扇形区所在边框的原点位置          
            Point circlePoint = new Point(Convert.ToInt32(textPoint.X + 270), 60);
            //总比 初始值           
            float totalRate = 0;
            //起始角度 Y周正方向          
            float startAngle = 30;
            //当前比 初始值          
            float currentRate = 0;
            //圆所在边框的大小  
            float currentAngle = 0;

            Size cicleSize = new Size(r * 2, r * 2);
            //圆所在边框的位置          
            Rectangle circleRectangle = new Rectangle(circlePoint, cicleSize);
            foreach (var item in data) totalRate += float.Parse(item.Value.ToString());
            foreach (var item in data)
            {
                currentRate = float.Parse(item.Value.ToString()) / totalRate * 360;
                currentAngle = (360 - startAngle - currentRate / 2);

                graphics.DrawPie(Pens.White, circleRectangle, startAngle, currentRate);
                graphics.FillPie(new SolidBrush(getColor(item.Key.ToString())), circleRectangle, startAngle, currentRate);
                //至此 扇形图已经画完，下面是在扇形图上写上说明文字

                //当前圆的圆心 相对图片边框原点的坐标             
                PointF cPoint = new PointF(circlePoint.X + r, circlePoint.Y + r);

                //当前圆弧上的点               
                //cos(弧度)=X轴坐标/r               
                //弧度=角度*π/180  

                double relativeCurrentX = r * Math.Cos((360 - startAngle - currentRate / 2) * Math.PI / 180);
                double relativecurrentY = r * Math.Sin((360 - startAngle - currentRate / 2) * Math.PI / 180);
                double currentX = relativeCurrentX + cPoint.X;
                double currentY = cPoint.Y - relativecurrentY;

                //内圆上弧上的 浮点型坐标               
                PointF currentPoint = new PointF(float.Parse(currentX.ToString()), float.Parse(currentY.ToString()));

                //外圆弧上的点         
                double largerR = r + 46;
                double relativeLargerX = largerR * Math.Cos((360 - startAngle - currentRate / 2) * Math.PI / 180);
                double relativeLargerY = largerR * Math.Sin((360 - startAngle - currentRate / 2) * Math.PI / 180);
                double largerX = relativeLargerX + cPoint.X;
                double largerY = cPoint.Y - relativeLargerY;

                //外圆上弧上的 浮点型坐标               
                PointF largerPoint = new PointF(float.Parse(largerX.ToString()), float.Parse(largerY.ToString()));
                //将两个点连起来                
                graphics.DrawLine(Pens.Black, currentPoint, largerPoint);
                //外圆上 说明文字的位置                
                PointF circleTextPoint = new PointF();
                circleTextPoint.X = largerPoint.X;
                circleTextPoint.Y = largerPoint.Y;

                string text = item.Key.ToString() + " " + (currentRate / 360).ToString("p2");
                Font font = new Font(familyName, 11);

                if (currentAngle >= 90 && currentAngle <= 270)
                {
                    circleTextPoint.X = largerPoint.X - graphics.MeasureString(text, font).Width;
                }

                if (currentAngle >= 0 && currentAngle <= 180)
                {
                    circleTextPoint.Y = largerPoint.Y - graphics.MeasureString(text, font).Height / 2;
                }


                //象限差异解释：在数学中 二维坐标轴中 右上方 全为正，在计算机处理图像时，右下方全为正。相当于顺时针移了一个象限序号                            
                graphics.DrawString(text, font, Brushes.Black, circleTextPoint);
                startAngle += currentRate;

            }
            return bitmap;
        }

        public void DrawPie(Graphics graphics, int width, int heigh, int r, string familyName, Dictionary<string, double> data)
        {
            //抗锯齿          
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            //高质量的文字          
            graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
            //像素均偏移0.5个单位，以消除锯齿          
            graphics.PixelOffsetMode = PixelOffsetMode.Half;
            //第一个色块的原点位置           
            PointF basePoint = new PointF(10, 20);

            //色块的大小          
            SizeF theSize = new SizeF(45, 16);
            //第一个色块的说明文字的位置           
            PointF textPoint = new PointF(basePoint.X + 50, basePoint.Y - 2);
            foreach (var item in data)
            {
                RectangleF baseRectangle = new RectangleF(basePoint, theSize);
                //画代表色块              
                graphics.FillRectangle(new SolidBrush(getColor(item.Key.ToString())), baseRectangle);
                graphics.DrawString(item.Key.ToString() + " :" + item.Value, new Font(familyName, 11), new SolidBrush(this.ForeColor), textPoint);
                basePoint.Y += 30;
                textPoint.Y += 30;
            }

            //扇形区所在边框的原点位置          
            Point circlePoint = new Point(Convert.ToInt32(textPoint.X + 270), 60);
            //总比 初始值           
            float totalRate = 0;
            //起始角度 Y周正方向          
            float startAngle = 30;
            //当前比 初始值          
            float currentRate = 0;
            //圆所在边框的大小  
            float currentAngle = 0;

            Size cicleSize = new Size(r * 2, r * 2);
            //圆所在边框的位置          
            Rectangle circleRectangle = new Rectangle(circlePoint, cicleSize);
            foreach (var item in data) totalRate += float.Parse(item.Value.ToString());
            foreach (var item in data)
            {
                currentRate = float.Parse(item.Value.ToString()) / totalRate * 360;
                currentAngle = (360 - startAngle - currentRate / 2);

                graphics.DrawPie(Pens.White, circleRectangle, startAngle, currentRate);
                graphics.FillPie(new SolidBrush(getColor(item.Key.ToString())), circleRectangle, startAngle, currentRate);
                //至此 扇形图已经画完，下面是在扇形图上写上说明文字

                //当前圆的圆心 相对图片边框原点的坐标             
                PointF cPoint = new PointF(circlePoint.X + r, circlePoint.Y + r);

                //当前圆弧上的点               
                //cos(弧度)=X轴坐标/r               
                //弧度=角度*π/180  

                double relativeCurrentX = r * Math.Cos((360 - startAngle - currentRate / 2) * Math.PI / 180);
                double relativecurrentY = r * Math.Sin((360 - startAngle - currentRate / 2) * Math.PI / 180);
                double currentX = relativeCurrentX + cPoint.X;
                double currentY = cPoint.Y - relativecurrentY;

                //内圆上弧上的 浮点型坐标               
                PointF currentPoint = new PointF(float.Parse(currentX.ToString()), float.Parse(currentY.ToString()));

                //外圆弧上的点         
                double largerR = r + 46;
                double relativeLargerX = largerR * Math.Cos((360 - startAngle - currentRate / 2) * Math.PI / 180);
                double relativeLargerY = largerR * Math.Sin((360 - startAngle - currentRate / 2) * Math.PI / 180);
                double largerX = relativeLargerX + cPoint.X;
                double largerY = cPoint.Y - relativeLargerY;

                //外圆上弧上的 浮点型坐标               
                PointF largerPoint = new PointF(float.Parse(largerX.ToString()), float.Parse(largerY.ToString()));
                //将两个点连起来                
                graphics.DrawLine(new Pen(this.ForeColor), currentPoint, largerPoint);
                //外圆上 说明文字的位置                
                PointF circleTextPoint = new PointF();
                circleTextPoint.X = largerPoint.X;
                circleTextPoint.Y = largerPoint.Y;

                string text = item.Key.ToString() + " " + (currentRate / 360).ToString("p2");
                Font font = new Font(familyName, 11);

                if (currentAngle >= 90 && currentAngle <= 270)
                {
                    circleTextPoint.X = largerPoint.X - graphics.MeasureString(text, font).Width;
                }

                if (currentAngle >= 0 && currentAngle <= 180)
                {
                    circleTextPoint.Y = largerPoint.Y - graphics.MeasureString(text, font).Height / 2;
                }

                //象限差异解释：在数学中 二维坐标轴中 右上方 全为正，在计算机处理图像时，右下方全为正。相当于顺时针移了一个象限序号                            
                graphics.DrawString(text, font, new SolidBrush(this.ForeColor), circleTextPoint);
                startAngle += currentRate;

            }

        }

        public void DrawFile(Graphics graphics, int width, int height, int x, int y, string familyName)
        {
            Font font = new Font(familyName, 11, FontStyle.Bold);
            Point TextPoint = new Point(10, y + 15);

            graphics.DrawString("版本信息：", font, new SolidBrush(ForeColor), TextPoint);
            font = new Font(familyName, 11, FontStyle.Regular);
            TextPoint.X += 45;
            TextPoint.Y += 40;

            graphics.DrawString(versionInfo, font, new SolidBrush(ForeColor), TextPoint);
            font = new Font(familyName, 11, FontStyle.Bold);

            TextPoint.X = 10;
            TextPoint.Y += 40;
            graphics.DrawString("文件信息：", font, new SolidBrush(ForeColor), TextPoint);
            font = new Font(familyName, 11, FontStyle.Regular);

            TextPoint.X += 45;
            TextPoint.Y += 40;

            Font smlfont = new Font(familyName, 9, FontStyle.Regular);
            StringFormat sf = new StringFormat();
            sf.LineAlignment = StringAlignment.Center;

            foreach (string key in file.Keys)
            {
                TextPoint.X = 10 + 45;

                DataBaseFileInfo dataBaseFileInfo = file[key] as DataBaseFileInfo;

                SizeF size = graphics.MeasureString(dataBaseFileInfo.Physical_Name, font);

                if (TextPoint.X + size.Width + 20 < width)
                {
                    graphics.DrawString(dataBaseFileInfo.Physical_Name, font, new SolidBrush(this.ForeColor), TextPoint);
                }
                else
                {
                    StringPlus sp = new StringPlus();
                    string physical_Name= sp.GetCnShortStr(dataBaseFileInfo.Physical_Name, 50, true);
                    graphics.DrawString(physical_Name, font, new SolidBrush(this.ForeColor), new Rectangle(TextPoint.X, TextPoint.Y, width - 2 * TextPoint.X, (int)size.Height), sf);
                }


                TextPoint.X += (int)Math.Ceiling(size.Width) + 20;

                string fileinfo = "文件大小：" + dataBaseFileInfo.Size + "MB  最大限制：" + "无限制";

                if (dataBaseFileInfo.Maxsize > 0)
                {
                    fileinfo = "文件大小：" + dataBaseFileInfo.Size + "MB  最大限制：" + dataBaseFileInfo.Maxsize + " MB";
                }

                size = graphics.MeasureString(fileinfo, font);

                if (TextPoint.X + size.Width + 20 < width)
                {
                    graphics.DrawString(fileinfo, font, new SolidBrush(this.ForeColor), TextPoint.X, TextPoint.Y);
                }

                TextPoint.X += (int)Math.Ceiling(size.Width) + 20;

                Rectangle baseRectangle = new Rectangle(TextPoint.X, TextPoint.Y, 200, (int)Math.Ceiling(size.Height));

                if (TextPoint.X + 200 < width)
                {
                    graphics.FillRectangle(new SolidBrush(Color.FromArgb(124, 187, 207)), baseRectangle);

                    if (dataBaseFileInfo.Maxsize > 0)
                    {
                        double nw = dataBaseFileInfo.Size / dataBaseFileInfo.Maxsize * baseRectangle.Width;
                        Rectangle newRectangle = new Rectangle(TextPoint.X, TextPoint.Y, (int)Math.Ceiling(nw), (int)Math.Ceiling(size.Height));
                        graphics.FillRectangle(new SolidBrush(Color.FromArgb(057, 134, 155)), newRectangle);
                    }
                    else
                    {
                        graphics.DrawString("最大限制：无限制", smlfont, new SolidBrush(Color.FromArgb(057, 134, 155)), baseRectangle, sf);
                    }

                    graphics.SmoothingMode = SmoothingMode.None;
                    graphics.PixelOffsetMode = PixelOffsetMode.Default;

                    graphics.DrawRectangle(new Pen(new SolidBrush(SystemColors.ControlDark)), baseRectangle);
                }

                TextPoint.Y += 40;

            }

        }

        Color getColor(string scoreLevel)
        {

            Color c = Color.White;

            if (scoreLevel.Contains("表"))
                c = Color.FromArgb(57, 134, 155);
            else if (scoreLevel.Contains("视图"))
                c = Color.FromArgb(70, 161, 185);
            else if (scoreLevel.Contains("存储过程"))
                c = Color.FromArgb(124, 187, 207);
            else if (scoreLevel.Contains("函数"))
                c = Color.FromArgb(181, 212, 224);
            else if (scoreLevel.Contains("其它"))
                c = Color.FromArgb(119, 174, 115);

            return c;

        }

    }
}
